#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>

	
#define SYSCALL_GET_222 222
#define SYSCALL_PUT_223 223
#define SYSCALL_DEL_251 251
	
#define TEST_LIMIT 10000000UL

struct test_data {
   char *value;
   size_t vsize;
   char *key;
   size_t ksize;
};

unsigned long ulrand(void){
	unsigned long ret = 0;

	ret = ((unsigned long)rand() & 0xffUL) << 16 |
		  ((unsigned long)rand() & 0xffUL) << 8  | 
		  ((unsigned long)rand() & 0xffUL);

	return ret;
}

void sys_del(const char *key, size_t ksize){
	syscall(SYSCALL_DEL_251, key, ksize); 
}

int main(int argc, char *argv[]){
	char key[100];
	char value[100];

	struct test_data data;
	data.key = key;
	data.value = value;

	/* generate random not repeated */
	unsigned int *arr = malloc(sizeof(int) * TEST_LIMIT);
	if(!arr)
		perror("malloc");
	
	/* init random arry */
	for(int i = 0; i < TEST_LIMIT; i++){
		arr[i] = i; 
		//fprintf(stderr, "arr[%d] = %d\n", i, i);
	}

	/* disordering */
	srand(time(NULL));
	for(unsigned int i = 0; i < TEST_LIMIT; i++){
		unsigned long rand;
		rand = ulrand();
		rand = rand % TEST_LIMIT;
				
		arr[i] = arr[i] ^ arr[rand];
		arr[rand] = arr[i] ^ arr[rand];
		arr[i] = arr[i] ^ arr[rand];
	}

	/* caculate runtime in ns */
	struct timespec time_start={0, 0}, time_end={0, 0};
	/* start timer */
	clock_gettime(CLOCK_REALTIME, &time_start);

	for(unsigned long cnt = 0; cnt < TEST_LIMIT; cnt++){
		sprintf(key, "%u", arr[cnt]);
		data.ksize = strlen(key) + 1;
		
		sys_del(data.key, data.ksize);	
		//fprintf(stderr, "del: key<%s>\n", key);
	}
	
	/* stop timer */
	clock_gettime(CLOCK_REALTIME, &time_end);
	if(time_end.tv_nsec < time_start.tv_nsec){
		printf("duration:%lus %luns\n", time_end.tv_sec - time_start.tv_sec - 1, 
					1000000000 + time_end.tv_nsec - time_start.tv_nsec);
	}
	else{
		printf("duration:%lus %luns\n", time_end.tv_sec - time_start.tv_sec, 
						time_end.tv_nsec - time_start.tv_nsec);
	}

	return 0;
}

